<?php
/**
 * Playcool Project
 *
 * LICENSE
 *
 * http://www.playcool.com/license/ice
 *
 * @category   ICE
 * @package    ChangeMe
 * @subpackage ChangeMe
 * @copyright  Copyright (c) 2008 Zeed Technologies PRC Inc. (http://www.inews.com.cn)
 * @author     xSharp ( GTalk: xSharp@gmail.com )
 * @since      Jun 3, 2009
 * @version    SVN: $Id: Benchmark.php 5594 2010-07-08 09:10:40Z nroe $
 */

class Benchmark
{
    /**
     * Benchmark timestamps
     *
     * @var array
     */
    private static $marks;
    private static $_resetThisCounter = false;
    
    /**
     * 重置开始时间
     *
     * @param unknown_type $name
     * @param unknown_type $resetAll 如果设置为 false，那么只清除上一次开始时间，并且下次结束时间也不做统计
     */
    public static function reset($name, $resetAll = true)
    {
        if (isset(self::$marks[$name])) {
            if ($resetAll) {
                self::$marks[$name] = array();
            } else {
                if (! empty(self::$marks[$name])) {
                    array_shift(self::$marks[$name]);
                    self::$_resetThisCounter = true;
                }
            }
        }
    }
    
    /**
     * Set a benchmark start point.
     *
     * @param   string  benchmark name
     * @return  void
     */
    public static function start($name)
    {
        if (! isset(self::$marks[$name])) {
            self::$marks[$name] = array();
        }
        
        $mark = array(
                'start' => microtime(TRUE),
                'stop' => FALSE,
                'memory_start' => self::memory_usage(),
                'memory_stop' => FALSE);
        
        array_unshift(self::$marks[$name], $mark);
    }
    
    /**
     * Set a benchmark stop point.
     *
     * @param   string  benchmark name
     * @return  void
     */
    public static function stop($name)
    {
        if (self::$_resetThisCounter) {
            self::$_resetThisCounter = false;
            return;
        }
        
        if (isset(self::$marks[$name]) and self::$marks[$name][0]['stop'] === FALSE) {
            self::$marks[$name][0]['stop'] = microtime(TRUE);
            self::$marks[$name][0]['memory_stop'] = self::memory_usage();
        }
    }
    
    /**
     * Get the elapsed time between a start and stop.
     *
     * @param   string   benchmark name, TRUE for all
     * @param   integer  number of decimal places to count to
     * @return  array
     */
    public static function get($name, $decimals = 4)
    {
        if ($name === TRUE) {
            $times = array();
            $names = array_keys(self::$marks);
            
            foreach ($names as $name) {
                // Get each mark recursively
                $times[$name] = self::get($name, $decimals);
            }
            
            // Return the array
            return $times;
        }
        
        if (! isset(self::$marks[$name]))
            return FALSE;
        
        if (empty(self::$marks[$name])) {
            return array(
                    'time' => 0,
                    'memory' => 0,
                    'count' => 0);
        }
        
        if (self::$marks[$name][0]['stop'] === FALSE) {
            // Stop the benchmark to prevent mis-matched results
            self::stop($name);
        }
        
        // Return a string version of the time between the start and stop points
        // Properly reading a float requires using number_format or sprintf
        $time = $memory = 0;
        $count = count(self::$marks[$name]);
        for ($i = 0; $i < $count; $i ++) {
            $time += self::$marks[$name][$i]['stop'] - self::$marks[$name][$i]['start'];
            $memory += self::$marks[$name][$i]['memory_stop'] - self::$marks[$name][$i]['memory_start'];
        }
        
        return array(
                'time' => number_format($time, $decimals),
                'memory' => number_format(($memory / 1024 / 1024), 4),
                'count' => $count);
    }
    
    /**
     * Returns the current memory usage. This is only possible if the
     * memory_get_usage function is supported in PHP.
     *
     * @return  integer
     */
    private static function memory_usage()
    {
        static $func = NULL;
        
        if ($func === NULL) {
            // Test if memory usage can be seen
            $func = function_exists('memory_get_usage');
        }
        
        return $func ? memory_get_usage() : 0;
    }
    
    /**
     * Colorful print_r()
     *
     * @param Array|String|Mixed $var
     * @param String $memo
     */
    public static function print_r($var, $memo = null)
    {
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            $color_bg = "RGB(" . rand(100, 255) . "," . rand(100, 255) . "," . rand(100, 255) . ")";
            if (! is_null($memo)) {
                $prefix = '<FIELDSET style="font-size:12px;font-family:Courier New;"><LEGEND style="padding:5px;">' . $memo . '</LEGEND>';
                $postfix = '</FIELDSET>';
            } else {
                $prefix = $postfix = "";
            }
            echo $prefix . '<pre style="font-size:12px;padding:5px;border-left:5px solid #0066cc;font-family:Courier New;color:black;text-align:left;background-color:' . $color_bg . '">' . "\n";
            print_r($var);
            echo "\n</pre>\n" . $postfix;
        } else {
            if (! is_null($memo)) {
                echo $memo . " - - - - -\n";
            }
            print_r($var);
            echo "\n";
        }
    }
    
    public static function println($str, $flush = true)
    {
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            echo $str . '<br />';
        } else {
            echo $str . "\n";
        }
        
        if ($flush) {
            flush();
        }
    }
}

// End ^ LF ^ UTF-8
